#include <fpc1020.h>
#include <uart2.h>
#include <motor.h>
#include <key.h>

//
#define GetTouch  rt_pin_read(PIN_TOUCH)

//
rt_tick_t start;


//
char fpc1020_wait_search 	= 0;
char fpc1020_wait_power_on  = 0;

int  fpc1020_rLen = 0;
char fpc1020_rBuf[8];

char fpc1020_search_success = 0;

//
static rt_timer_t timer; // 定时器的控制块

//定时器 超时函数
static void wait_timeout(void *parameter)
{
    //
	if(fpc1020_wait_power_on)
	{
		fpc1020_wait_power_on  = 0;

		FPC1020_LOG("fpc1020 wait power_on timeout \n");
	}
	else if(fpc1020_wait_search)
	{
		fpc1020_wait_search = 0;
		fpc1020_power(0);

		FPC1020_LOG("fpc1020 wait search timeout \n");
	}
}

static void timer_start(int ms)
{
	//启动一个定时器判断超时
	if (timer != RT_NULL) 
		rt_timer_delete(timer);
	
	FPC1020_LOG("rt_timer_start\n");
	timer = rt_timer_create(
		"timer_wait", 
		wait_timeout,
		RT_NULL,  
		ms / (1000 / RT_TICK_PER_SECOND),//
		RT_TIMER_FLAG_ONE_SHOT
	);
	rt_timer_start(timer);
}

static void timer_stop(void)
{
	rt_timer_stop(timer);
	FPC1020_LOG("rt_timer_stop\n");
}

//FPC1020主线程
static void thread_fpc1020_entry(void* parameter)
{
    int touch_t = 0;

    while (1)
    {
		//捕捉touch高电平 大于200ms有效
		if(GetTouch) touch_t++;
		else touch_t = 0;
		
		if(touch_t >= FPC1020_TOUCH_TIME/20)
		{
			touch_t = 0;
			start = rt_tick_get();
			
			FPC1020_LOG("fpc1020 touch trig\n");

			//如果在打开状态 则控制电机关闭
			if(LIMIT_UP)
			{
				motor_close();
			}
			else
			{
				//上电处理
				fpc1020_power_on();

				// 发送对比指令
				fpc1020_search();
			}
		}
        //
        rt_thread_mdelay(20);
    }
}

//FPC1020初始化
void fpc1020_init(void)
{
	//输入
    rt_pin_mode(PIN_TOUCH, PIN_MODE_INPUT_PULLDOWN);

    //输出powre
    rt_pin_mode(PIN_POWER, PIN_MODE_OUTPUT);

    //
    fpc1020_power(0);

    /* 创建fpc1020线程 */
    rt_thread_t tid = rt_thread_create("fpc1020",thread_fpc1020_entry,RT_NULL,1024,4,10);
    if (tid != RT_NULL) rt_thread_startup(tid);  

}


//异或校验
static char fpc1020_chk(char *data,char len)
{
	char i,temp = 0;

	for(i = 0; i < len; i++)
		temp ^= *(data + i);

	return temp;
}

//接收数据处理
void fpc1020_recv_process(void)
{
    char chk = fpc1020_chk(fpc1020_rBuf+1,5);
	if(fpc1020_rBuf[6] != chk)
    {
        FPC1020_LOG("fpc1020 chk err! Buf[6]:0x%02X != 0x%02X.\n",fpc1020_rBuf[6],chk);
      
		//
		fpc1020_wait_power_on = 0;
		fpc1020_wait_search = 0;
		fpc1020_power(0);
		timer_stop();
		
        return;
    }
    FPC1020_LOG("fpc1020 chk ok!\n"); 
	
	//CMD
   	switch(fpc1020_rBuf[1])
	{	
		//用户总数
		case FPC1020_CMD_USERNUMB:
			//等待上电信息
			if(fpc1020_wait_power_on)
			{
				fpc1020_wait_power_on = 0;
				timer_stop();
			}
		break;
		
		//1:N对比
        case FPC1020_CMD_SEARCH: 
			
            if( fpc1020_rBuf[4]>= 1 && fpc1020_rBuf[4] <= 3)
                fpc1020_search_success = 1;
            else
                FPC1020_LOG("fpc1020 search failed!\n");  

            //
            fpc1020_wait_search = 0;
            fpc1020_power(0);
            timer_stop();

            //控制电机开锁
            if(fpc1020_search_success)
            {
                motor_open();
            
				fpc1020_search_success = 0;
                FPC1020_LOG("fpc1020 search success!\n"); 

				rt_kprintf("finger used ticks : %d\n",rt_tick_get() - start); 
            }
                     
        break;
        default:  break;
    }
}

//上电时，指纹模块发送设备信息 F5 09 00 96 FF 00 60 F5,需要等待这一帧数据接收后在发送命令)
void fpc1020_power_on(void)
{
	fpc1020_rLen = 0;
	fpc1020_wait_power_on = 1;

	//超时控制
	timer_start(FPC1020_POWERON_TIMEOUT);

	fpc1020_power(1);

	while(fpc1020_wait_power_on)
	{rt_thread_mdelay(20);}
}

//1:N 对比
void fpc1020_search(void)
{
	fpc1020_rLen = 0;
	fpc1020_wait_search = 1;

	fpc1020_search_success = 0;

    //发送对比命令
    char buf[8];
    *buf     = FPC1020_DATA_START;          //1:N比对
    *(buf+1) = FPC1020_CMD_SEARCH;          //1:N比对
    *(buf+2) = 0x00;
    *(buf+3) = 0x00;
    *(buf+4) = 0x00;
    *(buf+5) = 0x00;
    *(buf+6) = fpc1020_chk(buf+1,5);
    *(buf+7) = FPC1020_DATA_END;
    uart2_write(buf,8);

	//超时控制
	timer_start(FPC1020_SEARCH_TIMEOUT);
	FPC1020_LOG("fpc1020 search wait... \n");

	while(fpc1020_wait_search)
	{rt_thread_mdelay(20);}
}


//FPC1020 供电
void fpc1020_power(int val)
{
    rt_pin_write(PIN_POWER,val?0:1);
    FPC1020_LOG("fpc1020_power : %d \n",val);
}


